package com.furentech.iotserver.fa.server.handler;

import com.furentech.iotserver.fa.server.ChannelUtil;
import com.furentech.iotserver.fa.sinopec.SinopecCRCUtil;
import com.furentech.iotserver.fa.sinopec.SinopecParam;
import com.furentech.iotserver.fa.utils.SpringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import java.util.ArrayList;

public class SinopecFaEncoder extends MessageToByteEncoder<byte[]> {

    ArrayList<Byte> byteArray=new   ArrayList<Byte>();

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, byte[] bytes, ByteBuf byteBuf) throws Exception {

        //get frameNum from channel dictionary
        byte frameNum = ChannelUtil.getChannelFrameNumber(channelHandlerContext.channel());
        byte devSourceAddr = ChannelUtil.getChannelDevSourceAddr(channelHandlerContext.channel());

        int validDataLength = bytes.length;

        int ge=validDataLength%10;
        int shi = (validDataLength % 100) / 10;
        int bai = (validDataLength % 1000) / 100;
        int qian = (validDataLength / 1000);

        byte shige = (byte) (0x00ff & (shi * 16 + ge));
        byte qianbai = (byte) (0x00ff & (qian * 16 + bai));


        SinopecParam sinopecParam=SpringUtil.getBean(SinopecParam.class);

        byteArray.clear();

        byteArray.add(devSourceAddr);
        byteArray.add((byte) (0x00ff & sinopecParam.destiAddr));
        byteArray.add(frameNum);

        byteArray.add(qianbai);
        byteArray.add(shige);

        for (int i = 0; i < validDataLength; i++) {
            byteArray.add(bytes[i]);
        }


        byte[] bufToCalCrc = new byte[byteArray.size()];

        for (int i = 0; i < bufToCalCrc.length; i++) {
            bufToCalCrc[i] = byteArray.get(i);
        }

        int crc= SinopecCRCUtil.calcCrc16WithAddr((devSourceAddr&0x00ff),sinopecParam.destiAddr,bufToCalCrc,2,bufToCalCrc.length-2);


        byteArray.add((byte)(0x00ff&(crc/256)));
        byteArray.add((byte)(0x00ff&(crc%256)));


        byte[] bufToAddFA=new byte[byteArray.size()];
        for (int i = 0; i < bufToAddFA.length; i++) {
            bufToAddFA[i] = byteArray.get(i);
        }

        byteArray.clear();

        byteArray.add((byte) (0xFA & 0x00ff));
        byteArray.add(bufToAddFA[0]);
        byteArray.add(bufToAddFA[1]);
        byteArray.add(bufToAddFA[2]);
        byteArray.add(bufToAddFA[3]);
        byteArray.add(bufToAddFA[4]);

        for (int i = 5; i < bufToAddFA.length; i++) {

            if((bufToAddFA[i]&0x00ff)==(0xFA&0x00ff))
            {
                byteArray.add((byte) (0xFA & 0x00ff));
            }
            byteArray.add(bufToAddFA[i]);
        }


        byte[] finalBuf = new byte[byteArray.size()];

        for (int i = 0; i < finalBuf.length; i++) {
            finalBuf[i] = byteArray.get(i);
        }

        byteBuf.writeBytes(finalBuf);
    }
}
